package aControllerLayer;

import java.awt.Point;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import aModelLayer.Character;
import aModelLayer.Direction;
import aModelLayer.Game;
import aModelLayer.Room;
import aModelLayer.Tile;
import aViewLayer.CharacterInRoomView;
import aViewLayer.View;
import aaGame.GameEngine;
import azServiceLayer.AudioPlayer;
import azServiceLayer.Input;
import azServiceLayer.R;

public class RoomController extends Controller{
	private Character mCharacter;
	private GameEngine mEngine;
	private boolean moving = false;
	private boolean lock = false;
	private boolean masterLock = false;
	private String direction;
	private Game mModel;
	private Room room;
	private CharacterInRoomView view;
	private Point pix;
	private Point tile;
	private int mKey = -100;
	private Tile cTile;
	
	private boolean battleArea;
	private boolean newBattle;
	private boolean checkOneTime;
	private Timer timer = null;
	private Room nextRoom;
	private AudioPlayer player;
	
	public RoomController(Game model, GameEngine engine){
		player = new AudioPlayer(this.getClass().getResource(R.music.legendaryEsper), AudioPlayer.MIDI);
		mModel = model;
		mCharacter = model.getCharacter();
		mEngine = engine;
		view = new CharacterInRoomView(model);
		room = mModel.getCurrentRoom();
		
		battleArea = true;
	}
	
	public void keyPressed(int key) {
		if (!masterLock){
			mKey = key;
			checkOneTime = true;
		}
		switch(key){
		case Input.Z:
			break;
		case Input.ENTER:
			break;
		case Input.ESCAPE:
			mEngine.currentController = mEngine.mPauseMenuController;
			mEngine.mPauseMenuController.playMusic();
			mEngine.printControllerName();
			break;
		}
	}

	public void keyReleased(int key) {
		if (key == mKey)
			mKey = -100;
	}

	public void update() {
		room = mModel.getCurrentRoom();
		
		switch(mKey){
		case Input.DOWN: 
			handleDirection(Direction.DOWN);
			break;
		case Input.UP:
			handleDirection(Direction.UP);
			break;
		case Input.LEFT: 
			handleDirection(Direction.LEFT);
			break;
		case Input.RIGHT:
			handleDirection(Direction.RIGHT);
			break;
		}
		
		pix = mCharacter.pixelPosition;
		tile = mCharacter.tilePosition;

		cTile = room.getCurrentTile(mCharacter.getTilePosition());
		if(cTile.getValue() == Tile.DOOR_TILE || cTile.getValue() == Tile.END_TILE)
			masterLock = true;
		else
			masterLock = false;
		if(moving){
			// if Character position arrived at the next tile
			if(pix.x == tile.x*32 && pix.y == tile.y*32){
				moving = false;
				lock = false;
				generateNewBattle();
				// Check the tile values 
				if(cTile.getValue() == Tile.DOOR_TILE)
					setDelay(300);
				else if (cTile.getValue() == Tile.END_TILE)
					setDelay(3000);
				else if (battleArea && newBattle) {
					newBattle = false;
					player.stopMusic();
					mEngine.startNewBattle();
					mKey = -100;
				}
				String test = "Character moved '"+direction+"'! ";
				test += "<<"+mCharacter.getTilePosition().toString()+">>";
				System.out.println(test); 

			} else {
				mCharacter.move(direction);
			}
		}
	}

	private void handleDirection(String direction) {
		mCharacter.setFacingDirection(direction);
		if (!lock)
			moving = setMotion(direction);
	}

	private void setDelay(int delay) {
		lock = true;
		if (checkOneTime){
			TimerTask task = setTimerTask();
			timer = new Timer();
			timer.schedule(task, delay);
			checkOneTime = false;
		}
	}

	private TimerTask setTimerTask() {
		TimerTask task = new TimerTask() {
			// Delays the loading of a room (allowing the view to fade in and out)
			@Override
			public void run() {
				String link = room.getTargets().get(tile);
				String[] result = link.split("#", 2);
				String from = result[0];
				String to = result[1];
				if (to.equals("random")) {
					Random generator = new Random();
					nextRoom = new Room("floor" + (generator.nextInt(2) + 1));
				} else {
					nextRoom = new Room(from, to, mCharacter);
				}
				System.out.println("POSITION: "+tile.toString());
				mCharacter.setTilePosition(nextRoom.getStartPosition());
				mModel.setCurrentRoom(nextRoom);
				masterLock = false;
				lock = false;
			}
		};
		return task;
	}

	private boolean setMotion(String dir) {
		this.direction = dir;
		boolean emptyTile;
		Point ctp = mCharacter.getTilePosition();
		emptyTile = room.isAdjacentTileEmpty(dir, ctp);
		if (emptyTile){
			mCharacter.changeTilePosition(dir);
			lock = true;
			return true;
		} else {
			System.out.println("You hit a wall!");
			return false;
		}
	}

	@Override
	public View getView() {
		return view;
	}
	
	public void playMusic(){
		player.playMusic();
	}
	
	public void stopMusic() {
		player.stopMusic();
	}
	
	private boolean generateNewBattle() {
		Random generator = new Random();
		if (generator.nextInt(100) == 0) {
			newBattle = true;
		} else {
			newBattle = false;
		}		
		return newBattle;
	}

}
